#!/bin/bash
#$1 - the file containing the passwords
#$2 - the number of characters used to generate the password
charset=`echo 1 2 3 4 8 9 0 b d f h n s A H M`
#for each row from the passwords file
for i in `cat $1`
do
  #extracting the user name, the encrypted password and the salt information
  user=`echo $i | cut -d: -f1`
  encpass=`echo $i | cut -d: -f2`
  salt=`echo $encpass | cut -c-2`
  found=0
#echoing the user name for which we are trying to find the password
echo $user
  #if the second argument is greater or equal with 1 we test all passwords 
  #generated using a character from the charset
  if [ $2 -ge 1 ]
  then
  for l1 in $charset
  do 
#echoing the generated password
echo $l1
     #encrypting the password
     newpass=$(perl -e'print crypt($ARGV[0], $ARGV[1])' $l1 $salt)
     #if the password is found
     if [ "$encpass" == "$newpass" ]
     then
        found=1
        #adding the password to the decoded passwords list
        echo  $user:`echo $l1` >> decoded_pass.txt
     fi
     #if the password was not found and the second argument is greater or equal with 2
     #then execute the same procedure for combinations of 2 characters
     if [ $found -eq 0 -a $2 -ge 2 ]
     then
        for l2 in $charset
        do
echo $l1$l2
           newpass=$(perl -e'print crypt($ARGV[0], $ARGV[1])' $l1$l2 $salt)
           if [ "$encpass" == "$newpass" ]
           then
               found=1
               echo  $user:`echo $l1$l2` >> decoded_pass.txt
           fi
           #if the password was not found and the second argument is greater or equal with 3
           #then execute the same procedure for combinations of 3 characters
           if [ $found -eq 0 -a $2 -ge 3 ]
           then
               for l3 in $charset
               do
echo $l1$l2$l3
                 newpass=$(perl -e'print crypt($ARGV[0], $ARGV[1])' $l1$l2$l3 $salt)
                 if [ "$encpass" == "$newpass" ]
                 then
                     found=1
                     echo  $user:`echo $l1$l2$l3` >> decoded_pass.txt
                 fi
           #if the password was not found and the second argument is greater or equal with 4
           #then execute the same procedure for combinations of 4 characters
           if [ $found -eq 0 -a $2 -ge 4 ]
           then
               for l4 in $charset
               do
echo $l1$l2$l3$l4
                 newpass=$(perl -e'print crypt($ARGV[0], $ARGV[1])' $l1$l2$l3$l4 $salt)
                 if [ "$encpass" == "$newpass" ]
                 then
                     found=1
                     echo  $user:`echo $l1$l2$l3$l4` >> decoded_pass.txt
                 fi
                 #if the password was not found and the second argument is greater or equal with 5
                 #then execute the same procedure for combinations of 5 characters
                 if [ $found -eq 0 -a $2 -ge 5 ]
                 then
                     for l5 in $charset
                     do
echo $l1$l2$l3$l4$l5
                        newpass=$(perl -e'print crypt($ARGV[0], $ARGV[1])' $l1$l2$l3$l4$l5 $salt)
                        if [ "$encpass" == "$newpass" ]
                        then
                            found=1
                            echo  $user:`echo $l1$l2$l3$l4$l5` >> decoded_pass.txt
                        fi
                        #if the password was not found and the second argument is greater or equal with 6
                        #then execute the same procedure for combinations of 6 characters
                        if [ $found -eq 0 -a $2 -ge 6 ]
                        then
                            for l6 in $charset
                            do
echo $l1$l2$l3$l4$l5$l6
                               newpass=$(perl -e'print crypt($ARGV[0], $ARGV[1])' $l1$l2$l3$l4$l5$l6 $salt)
                               if [ "$encpass" == "$newpass" ]
                               then
                                   found=1
                                   echo  $user:`echo $l1$l2$l3$l4$l5$l6` >> decoded_pass.txt
                               fi
                               #if the password was not found and the second argument is greater or equal with 7
                               #then execute the same procedure for combinations of 7 characters
                               if [ $found -eq 0 -a $2 -ge 7 ]
                               then
                               for l7 in $charset
                               do
echo $l1$l2$l3$l4$l5$l6$l7
                                 newpass=$(perl -e'print crypt($ARGV[0], $ARGV[1])' $l1$l2$l3$l4$l5$l6$l7 $salt)
                                 if [ "$encpass" == "$newpass" ]
                                 then
                                     found=1
                                     echo  $user:`echo $l1$l2$l3$l4$l5$l6$l7` >> decoded_pass.txt
                                 fi
                                 #if the password was not found and the second argument is greater or equal with 8
                                 #then execute the same procedure for combinations of maximum 8 characters (limit imposed by DES)
                                 if [ $found -eq 0 -a $2 -ge 8 ]
                                 then
                                     for l8 in $charset
                                     do
echo $l1$l2$l3$l4$l5$l6$l7$l8
                                        newpass=$(perl -e'print crypt($ARGV[0], $ARGV[1])' $l1$l2$l3$l4$l5$l6$l7$l8 $salt)
                                        if [ "$encpass" == "$newpass" ]
                                        then
                                            found=1
                                            echo  $user:`echo $l1$l2$l3$l4$l5$l6$l7$l8` >> decoded_pass.txt
                                        fi
                                      done
                                  fi
                                done
                           fi

                        done
                     fi

                  done
                fi

              done
             fi
            done   
           fi
        done
     fi
  done
fi
done
